package com.example.article.controller;

import com.alibaba.fastjson.JSON;
import com.example.article.entity.Condition;
import com.example.article.vo.ArticleEntityVo;
import com.example.commonutils.JwtUtils;
import com.example.commonutils.ResultData;
import io.netty.util.internal.StringUtil;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/article/es")
public class ElasticSearchController {
    private RestHighLevelClient client;

    //分页查询文档排序及高亮显示
    @PostMapping(value = "getPageForDoc/{page}/{limit}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResultData getPageForDoc(@PathVariable("page") long page,
                                    @PathVariable("limit") long limit,
                                    @RequestBody() Condition condition,
                                    HttpServletRequest request) throws IOException {
        client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.241.128:9200")));
        //准备request
        SearchRequest esRequest = new SearchRequest("article");
        //准备dsl
        if (!StringUtil.isNullOrEmpty(condition.getCondition())) {
            //条件不为空
            esRequest.source().query(QueryBuilders.matchQuery("all", condition.getCondition()));
        } else {
            //条件为空则查询所有即可
            esRequest.source().query(QueryBuilders.matchAllQuery());
        }
        //判断查询条件 1表示按时间降序 2表示按浏览数降序 3表示只看我自己的
        if ("1".equals(condition.getSort())) {
            esRequest.source().sort("gmtCreate",SortOrder.DESC);
        } else if ("2".equals(condition.getSort())) {
            esRequest.source().sort("viewCount",SortOrder.DESC);
        } else if ("3".equals(condition.getSort())) {
            //从请求中获取token
            String token = JwtUtils.getMemberIdByJwtToken(request);
            String memberId = "";
            if (!StringUtil.isNullOrEmpty(token)) {
                memberId = JwtUtils.getMemberIdByJwtToken(request);
            }
           esRequest.source().query(QueryBuilders.termQuery("userId",memberId));
        }
        esRequest.source().from((int) ((page - 1) * limit)).size((int) limit);
        //将搜索关键字高亮显示
        esRequest.source().highlighter(new HighlightBuilder()
                .field("title")
                //是否需要字段匹配
                .requireFieldMatch(false)
                .preTags("<em style='color: orangered;font-weight:bold;'>")
                .postTags("</em>")
        );
        //发送请求
        SearchResponse response = client.search(esRequest, RequestOptions.DEFAULT);
        //解析结果
        SearchHits hits = response.getHits();
        //获取查询总数
        long total = hits.getTotalHits().value;
        List<ArticleEntityVo> list = handlerResponse(response);
        client.close();
        return ResultData.ok().data("total", total).data("articleInfo", list);
    }

    public List<ArticleEntityVo> handlerResponse(SearchResponse response) {
        List<ArticleEntityVo> list = new ArrayList<>();
        SearchHits hits = response.getHits();
        //拿到所有数据
        SearchHit[] hits1 = hits.getHits();
        for (SearchHit hit : hits1) {
            //拿到数据部分
            String json = hit.getSourceAsString();
            ArticleEntityVo esArticleInfo = JSON.parseObject(json, ArticleEntityVo.class);
            //替换高亮部分
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (highlightFields != null) {
                HighlightField title = highlightFields.get("title");
                if (title != null) {
                    String name = title.getFragments()[0].string();
                    esArticleInfo.setTitle(name);
                }
                HighlightField summary = highlightFields.get("summary");
                if (summary!=null){
                    String string = summary.getFragments()[0].string();
                    esArticleInfo.setSummary(string);
                }
            }
            list.add(esArticleInfo);
        }
        return list;
    }

    @GetMapping(value = "autoCompletion/{condition}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResultData autoCompletion(@PathVariable(required = false) String condition) throws IOException {
        client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.241.128:9200")));
        //准备request
        SearchRequest request = new SearchRequest("article");
        //准备dsl
        if (StringUtil.isNullOrEmpty(condition)) {
            request.source().query(QueryBuilders.matchAllQuery());
        } else {
            request.source().query(QueryBuilders.matchQuery("all", condition));
        }
        //查询前五条
        request.source().from(0).size(5);
        //将搜索关键字高亮显示
        request.source().highlighter(new HighlightBuilder()
                .field("title")
                //是否需要字段匹配
                .requireFieldMatch(false)
                .preTags("<em style='color: orangered;font-weight:bold;'>")
                .postTags("</em>")
        );
        //发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //解析结果
        SearchHits hits = response.getHits();
        SearchHit[] hits1 = hits.getHits();
        List<Map> list = new ArrayList<>();
        for (SearchHit hit : hits1) {
            Map<String, String> map = new HashMap<>();
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (highlightFields != null) {
                HighlightField title = highlightFields.get("title");
                if (title != null) {
                    String name = title.getFragments()[0].string();
                    map.put("value", name);
                }
            }
            String json = hit.getSourceAsString();
            ArticleEntityVo esCourseInfo = JSON.parseObject(json, ArticleEntityVo.class);
            map.put("title", esCourseInfo.getTitle());
            list.add(map);
        }
        client.close();
        return ResultData.ok().data("list", list);
    }
}
